package typedefault

import (
	"codejy/globalfunc"
	"codejy/store"
	"codejy/structdef"
	"codejy/utils"
	"strconv"
	"strings"
)

// key 实例地址,value 值

type System struct {
	Addr        string
	ThreadStore *structdef.ThreadStore
}

func (f *System) CreateTypeDefault(addr string, threadStore *structdef.ThreadStore, parameter ...string) {
	fUtil := &System{
		Addr:        addr,
		ThreadStore: threadStore,
	}
	store.AddTypeDefaultInstanceStore(threadStore, f.GetTypeName(), addr, fUtil)
}
func (f *System) GetData() interface{} {
	return nil
}

func (a *System) ToStr() string {
	return ""
}
func (a *System) ParameterProcessing(parameter []string) []string {
	//排除前后""
	for i := range parameter {
		s := parameter[i]
		if strings.HasPrefix(s, "\"") && strings.HasSuffix(s, "\"") {
			s = s[1 : len(s)-1]
			parameter[i] = s
		}
	}
	return parameter
}

// 获取当前是什么系统
func (a *System) GetSystem() string {
	return utils.GetSystem()
}

// 获取当前系统的架构
func (a *System) GetArch() string {
	return utils.GetArch()
}

// 获取当前系统的cpu核心数
func (a *System) GetCpuNum() string {
	return strconv.Itoa(utils.GetCpuNum())
}

// 获取当前程序分配的总内存,单位MB(实时的)
func (a *System) GetMem() string {
	return strconv.FormatFloat(utils.GetMem(), 'f', 3, 64)
}

// 获取当前程序使用的协程数
func (a *System) GetNumGoroutine() string {
	goroutine := utils.GetNumGoroutine()
	return strconv.Itoa(goroutine)
}

// 获取系统环境变量
func (a *System) GetEnv(key string) string {
	return utils.GetEnv(key)
}

// 添加系统环境变量,如果已经存在,则覆盖
func (a *System) SetEnv(key string, value string) {
	utils.SetEnv(key, value)
}

// 删除系统环境变量
func (a *System) DelEnv(key string) {
	utils.UnsetEnv(key)
}

// 判断系统环境变量是否存在
func (a *System) IsEnv(key string) string {
	return strconv.FormatBool(utils.IsEnvExist(key))
}

// 获取全部的系统环境变量，返回Map
func (a *System) GetEnviron() string {
	environ := utils.Environ()
	//转Map
	var addrMap = globalfunc.ExecuteFunc("MapToMap", environ, a.ThreadStore).(string)
	return addrMap
}

// 添加path环境变量
func (a *System) AddPathEnv(value string) {
	utils.SetPathEnv(value)
}

// 删除path环境变量
func (a *System) DelPathEnv(value string) {
	utils.UnsetPathEnv(value)
}

// 将当前程序所在目录添加到path环境变量
func (a *System) AddPathEnvCurrent() {
	utils.SetCurrentPathToPathEnv()
}

// 获取进程id
func (a *System) GetPid() string {
	return strconv.Itoa(utils.GetPid())
}

// 杀死指定进程
func (a *System) KillPid(pid string) {
	i, err := strconv.Atoi(pid)
	if err != nil {
		panic(err)
	}
	utils.KillPid(i)
}

// 启动一个进程，返回进程id
func (a *System) StartProcess(args string) string {
	//如果是List,那么打印出来
	value, b := GetTypeDefaultValue[[]string](a.ThreadStore, "List", args)
	if !b {
		panic("System-StartProcess(?)参数错误")
	}
	var path = value[0]
	//去除引号
	path = StrToString(path)
	//处理特殊符号,还原
	path = SpecificSymbol(path)
	var argsList = value[1:]
	processId := utils.StartProcess(path, argsList...)
	return strconv.Itoa(processId)
}

// 等待一个进程结束，返回进程状态码
func (a *System) WaitProcess(pid string) string {
	i, err := strconv.Atoi(pid)
	if err != nil {
		panic(err)
	}
	return strconv.Itoa(utils.WaitProcess(i))
}

func (f *System) GetDef() string {
	return `
		@CodeManual(def="System.xxx",des="系统相关操作")
		type share System{
			def init{
				core&CreateTypeDefault()
			}
			@CodeManual(def="System.os",des="获取当前是什么系统，返回值为windows,linux...")
			def os{
				to core&GetSystem()
			}
			@CodeManual(def="System.arch",des="获取当前系统的架构，返回值为amd64,386...")
			def arch {
				to core&GetArch()
			}
			@CodeManual(def="System.cpuNum",des="获取当前系统的cpu核心数，返回值为数字")
			def cpuNum{
				to core&GetCpuNum()
			}
			@CodeManual(def="System.mem",des="获取当前程序分配的总内存,单位MB(实时的)")
			def mem{
				to core&GetMem()
			}
			@CodeManual(def="System.threadNum",des="获取当前程序使用的协程数")
			def threadNum{
				to core&GetNumGoroutine()
			}
			@CodeManual(def="System.env($1)",des="获取系统环境变量,$1是环境变量的key")
			def env{
				to core&GetEnv($1)
			}
			@CodeManual(def="System.pid",des="获取进程id")
			def pid{
				to core&GetPid()
			}
			@CodeManual(def="System.kill($1)",des="杀死指定进程,$1是进程id")
			def kill{
				core&KillPid($1)
			}
			@CodeManual(def="System.start($1)",des="启动一个进程，返回进程id,$1是进程路径，$2是参数列表")
			def startProcess{
				to core&StartProcess($1)
			}
			@CodeManual(def="System.wait($1)",des="等待一个进程结束，返回进程状态码,$1是进程id")
			def wait{
				to core&WaitProcess($1)
			}

		}
	`
}

func init() {
	RegisterTypeDefault(&System{})
}
func (f *System) GetTypeName() string {
	return "System"
}
